package com.zzs.client.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zzs.client.dao.mysql.ProblemMapper;
import com.zzs.client.dao.redis.ProblemCacheManager;
import com.zzs.client.pojo.query.ProblemQuery;
import com.zzs.client.pojo.vo.problem.ProblemDetailVO;
import com.zzs.client.pojo.vo.problem.ProblemVO;
import com.zzs.client.service.ProblemService;
import com.zzs.common.core.constant.RedisKeyConsts;
import com.zzs.common.core.entity.mysql.ProblemDO;
import com.zzs.common.core.entity.redis.ProblemCache;
import com.zzs.common.core.enums.ResponseCode;
import com.zzs.common.core.response.PageResult;
import com.zzs.common.redis.service.RedisService;
import com.zzs.common.security.exception.ServiceException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author zzs
 * @date 2025/03/25
 */
@Service
public class ProblemServiceImpl implements ProblemService {
    @Autowired
    private ProblemCacheManager problemCacheManager;
    @Autowired
    private ProblemMapper problemMapper;
    @Autowired
    private RedisService redisService;

    @Override
    public ProblemDetailVO getProblemDetail(long problemId) {
        ProblemDetailVO problemDetailVO = new ProblemDetailVO();
        ProblemCache problemCache = problemCacheManager.get(problemId);
        if (problemCache != null) {
//            redis中有缓存
            BeanUtils.copyProperties(problemCache, problemDetailVO);
        } else {
//            redis中没有缓存
            ProblemDO problemDO = problemMapper.get(problemId);
            if (problemDO == null) {
                throw new ServiceException(ResponseCode.NOT_FOUND, "题目不存在");
            }
            BeanUtils.copyProperties(problemDO, problemDetailVO);
            problemCache = new ProblemCache();
            BeanUtils.copyProperties(problemDO, problemCache);
//            刷新redis
            problemCacheManager.save(problemCache);
        }
        return problemDetailVO;
    }

    @Override
    public PageResult<ProblemVO> listProblems(ProblemQuery problemQuery) {
//        没有模糊查询, 就走redis; 有模糊查询, 走mysql全文索引
        if (problemQuery.getKeyword() == null || problemQuery.getKeyword().isBlank()) {
            List<ProblemCache> problemCacheList = problemCacheManager.listProblemCaches(problemQuery.getDifficulty(), problemQuery.getPageSize(), problemQuery.getPageNum());
            long total = redisService.getSizeForZset(RedisKeyConsts.getProblemIdZsetKey(problemQuery.getDifficulty()));
            if (problemCacheList == null || problemCacheList.isEmpty()) {
                return PageResult.empty((int) total);
            }
            List<ProblemVO> problemVOList = problemCacheList.stream()
                    .map(problemCache -> {
                        ProblemVO problemVO = new ProblemVO();
                        BeanUtils.copyProperties(problemCache, problemVO);
                        return problemVO;
                    }).toList();
            return PageResult.success((int) total, problemVOList);
        } else {
            PageHelper.startPage(problemQuery.getPageNum(), problemQuery.getPageSize());
            List<ProblemDO> problemDOList = problemMapper.listPublishProblems(problemQuery.getDifficulty(), problemQuery.getKeyword());
            PageInfo<ProblemDO> pageInfo = new PageInfo<>(problemDOList);
            List<ProblemVO> rows = problemDOList.stream()
                    .map(problemDO -> {
                        ProblemVO problemVO = new ProblemVO();
                        BeanUtils.copyProperties(problemDO, problemVO);
                        return problemVO;
                    }).toList();
            return PageResult.success((int) pageInfo.getTotal(), rows);
        }
    }

    @Override
    public long getPrevProblemId(long problemId) {
        return problemCacheManager.getPrevProblemId(problemId);
    }

    @Override
    public long getNextProblemId(long problemId) {
        return problemCacheManager.getNextProblemId(problemId);
    }
}
